package com.demo.cryptology.symmetric;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import java.security.SecureRandom;
import java.util.Base64;

/**
 * 3DES（或称为Triple DES）是三重数据加密算法（TDEA，Triple Data Encryption Algorithm）块密码的通称。
 * 它相当于是对每个数据块应用三次DES加密算法。由于计算机运算能力的增强，原版DES密码的密钥长度变得容易被暴力破解；
 * 3DES即是设计用来提供一种相对简单的方法，即通过增加DES的密钥长度来避免类似的攻击，而不是设计一种全新的块密码算法。
 *
 */
public class DESSede {
    /**
     * DES,DESede,Blowfish
     * DES 密要64位
     * DESede 192
     * Blowfish 8
     *
     * @return
     * @throws Exception
     */
    public static byte[] encrypt(byte[] datasource, String password) throws Exception {
        SecureRandom random = new SecureRandom();
        DESedeKeySpec desKey = new DESedeKeySpec(password.getBytes());
        //创建一个密钥工厂，然后用它把DESKeySpec转换成
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        SecretKey securekey = keyFactory.generateSecret(desKey);
        //cipher对象世纪完成加密操作
        Cipher cipher = Cipher.getInstance("DESede");
        //用密钥初始化cipher对象
        cipher.init(cipher.ENCRYPT_MODE, securekey, random);
        //现在，获取数据并加密
        //正式执行加密操作
        byte[] r = cipher.doFinal(datasource);
        return encoder.encode(r);
    }


    public static byte[] decrypt(byte[] src, String password) throws Exception {
        src = decoder.decode(src);
        //DES算法要求有一个可信任的随即数源
        SecureRandom random = new SecureRandom();
        DESedeKeySpec deskey = new DESedeKeySpec(password.getBytes("utf-8"));
        //创建一个密钥工厂
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        //将DESKeySpec对象转换成secretKey对象
        SecretKey secretKey = keyFactory.generateSecret(deskey);
        //cipher对象世纪完成解密操作
        Cipher cipher = Cipher.getInstance("DESede");
        cipher.init(cipher.DECRYPT_MODE, secretKey, random);
        return cipher.doFinal(src);

    }

    static final Base64.Decoder decoder = Base64.getDecoder();
    static final Base64.Encoder encoder = Base64.getEncoder();

    public static void main(String[] args) throws Exception {
        String str = "代价密数据";
        //长度是8的倍数
        String password = "xUHdKxzVCbsgVIwTnc1jtpWn";
        byte[] result = DESSede.encrypt(str.getBytes("utf-8"), password);
        System.out.println("加密后:" + new String(result, "utf-8"));

//        String baseStr = encoder.encodeToString(result);
//        System.out.println("base64加密des密文:" + baseStr);
//        byte[] resp = decoder.decode(baseStr.getBytes());
//        System.out.println("base解码des密文:" + new String(resp));

        byte[] decryResult = DESSede.decrypt(result, password);
        System.out.println("解密后:" + new String(decryResult));

    }
}
